home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / sml_nj / 93src.lha / src / parse / base.sml < prev    next >
Encoding:
Text File  |  1993-01-27  |  33.0 KB  |  1,041 lines

  1. (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)
  2.  
  3. (* base.sig: Base signature file for SML-Yacc.  This file contains signatures
  4.    that must be loaded before any of the files produced by ML-Yacc are loaded
  5. *)
  6.  
  7. (* STREAM: signature for a lazy stream.*)
  8.  
  9. signature STREAM =
  10.  sig type 'xa stream
  11.      val streamify : (unit -> '_a) -> '_a stream
  12.      val cons : '_a * '_a stream -> '_a stream
  13.      val get : '_a stream -> '_a * '_a stream
  14.  end
  15.  
  16. (* LR_TABLE: signature for an LR Table.
  17.  
  18.    The list of actions and gotos passed to mkLrTable must be ordered by state
  19.    number. The values for state 0 are the first in the list, the values for
  20.     state 1 are next, etc.
  21. *)
  22.  
  23. signature LR_TABLE =
  24.     sig
  25.         datatype ('a,'b) pairlist = EMPTY | PAIR of 'a * 'b * ('a,'b) pairlist
  26.     datatype state = STATE of int
  27.     datatype term = T of int
  28.     datatype nonterm = NT of int
  29.     datatype action = SHIFT of state
  30.             | REDUCE of int
  31.             | ACCEPT
  32.             | ERROR
  33.     type table
  34.     
  35.     val numStates : table -> int
  36.     val numRules : table -> int
  37.     val describeActions : table -> state ->
  38.                 (term,action) pairlist * action
  39.     val describeGoto : table -> state -> (nonterm,state) pairlist
  40.     val action : table -> state * term -> action
  41.     val goto : table -> state * nonterm -> state
  42.     val initialState : table -> state
  43.     exception Goto of state * nonterm
  44.  
  45.     val mkLrTable : {actions : ((term,action) pairlist * action) array,
  46.              gotos : (nonterm,state) pairlist array,
  47.              numStates : int, numRules : int,
  48.              initialState : state} -> table
  49.     end
  50.  
  51. (* TOKEN: signature revealing the internal structure of a token. This signature
  52.    TOKEN distinct from the signature {parser name}_TOKENS produced by ML-Yacc.
  53.    The {parser name}_TOKENS structures contain some types and functions to
  54.     construct tokens from values and positions.
  55.  
  56.    The representation of token was very carefully chosen here to allow the
  57.    polymorphic parser to work without knowing the types of semantic values
  58.    or line numbers.
  59.  
  60.    This has had an impact on the TOKENS structure produced by SML-Yacc, which
  61.    is a structure parameter to lexer functors.  We would like to have some
  62.    type 'a token which functions to construct tokens would create.  A
  63.    constructor function for a integer token might be
  64.  
  65.       INT: int * 'a * 'a -> 'a token.
  66.  
  67.    This is not possible because we need to have tokens with the representation
  68.    given below for the polymorphic parser.
  69.  
  70.    Thus our constructur functions for tokens have the form:
  71.  
  72.       INT: int * 'a * 'a -> (svalue,'a) token
  73.  
  74.    This in turn has had an impact on the signature that lexers for SML-Yacc
  75.    must match and the types that a user must declare in the user declarations
  76.    section of lexers.
  77. *)
  78.  
  79. signature TOKEN =
  80.     sig
  81.     structure LrTable : LR_TABLE
  82.         datatype ('a,'b) token = TOKEN of LrTable.term * ('a * 'b * 'b)
  83.     val sameToken : ('a,'b) token * ('a,'b) token -> bool
  84.     end
  85.  
  86. (* LR_PARSER: signature for a polymorphic LR parser *)
  87.  
  88. signature LR_PARSER =
  89.     sig
  90.     structure Stream: STREAM
  91.     structure LrTable : LR_TABLE
  92.     structure Token : TOKEN
  93.  
  94.     sharing LrTable = Token.LrTable
  95.  
  96.     exception ParseError
  97.  
  98.     val parse : {table : LrTable.table,
  99.              lexer : ('_b,'_c) Token.token Stream.stream,
  100.              arg: 'arg,
  101.              saction : int *
  102.                    '_c *
  103.                 (LrTable.state * ('_b * '_c * '_c)) list * 
  104.                 'arg ->
  105.                      LrTable.nonterm *
  106.                      ('_b * '_c * '_c) *
  107.                      ((LrTable.state *('_b * '_c * '_c)) list),
  108.              void : '_b,
  109.              ec : { is_keyword : LrTable.term -> bool,
  110.                 noShift : LrTable.term -> bool,
  111.                 preferred_subst : LrTable.term -> LrTable.term list,
  112.                 preferred_insert : LrTable.term -> bool,
  113.                 errtermvalue : LrTable.term -> '_b,
  114.                 showTerminal : LrTable.term -> string,
  115.                 terms: LrTable.term list,
  116.                 error : string * '_c * '_c -> unit
  117.                },
  118.              lookahead : int  (* max amount of lookahead used in *)
  119.                       (* error correction *)
  120.             } -> '_b *
  121.                  (('_b,'_c) Token.token Stream.stream)
  122.     end
  123.  
  124. (* LEXER: a signature that most lexers produced for use with SML-Yacc's
  125.    output will match.  The user is responsible for declaring type token,
  126.    type pos, and type svalue in the UserDeclarations section of a lexer.
  127.  
  128.    Note that type token is abstract in the lexer.  This allows SML-Yacc to
  129.    create a TOKENS signature for use with lexers produced by ML-Lex that
  130.    treats the type token abstractly.  Lexers that are functors parametrized by
  131.    a Tokens structure matching a TOKENS signature cannot examine the structure
  132.    of tokens.
  133. *)
  134.  
  135. signature LEXER =
  136.    sig
  137.        structure UserDeclarations :
  138.        sig
  139.             type ('a,'b) token
  140.         type pos
  141.         type svalue
  142.        end
  143.     val makeLexer : (int -> string) -> unit -> 
  144.          (UserDeclarations.svalue,UserDeclarations.pos) UserDeclarations.token
  145.    end
  146.  
  147. (* ARG_LEXER: the %arg option of ML-Lex allows users to produce lexers which
  148.    also take an argument before yielding a function from unit to a token
  149. *)
  150.  
  151. signature ARG_LEXER =
  152.    sig
  153.        structure UserDeclarations :
  154.        sig
  155.             type ('a,'b) token
  156.         type pos
  157.         type svalue
  158.         type arg
  159.        end
  160.     val makeLexer : (int -> string) -> UserDeclarations.arg -> unit -> 
  161.          (UserDeclarations.svalue,UserDeclarations.pos) UserDeclarations.token
  162.    end
  163.  
  164. (* PARSER_DATA: the signature of ParserData structures in {parser name}LrValsFun
  165.    produced by  SML-Yacc.  All such structures match this signature.  
  166.  
  167.    The {parser name}LrValsFun produces a structure which contains all the values
  168.    except for the lexer needed to call the polymorphic parser mentioned
  169.    before.
  170.  
  171. *)
  172.  
  173. signature PARSER_DATA =
  174.    sig
  175.         (* the type of line numbers *)
  176.  
  177.     type pos
  178.  
  179.     (* the type of semantic values *)
  180.  
  181.     type svalue
  182.  
  183.          (* the type of the user-supplied argument to the parser *)
  184.      type arg
  185.  
  186.     (* the intended type of the result of the parser.  This value is
  187.        produced by applying extract from the structure Actions to the
  188.        final semantic value resultiing from a parse.
  189.      *)
  190.  
  191.     type result
  192.  
  193.     structure LrTable : LR_TABLE
  194.     structure Token : TOKEN
  195.     sharing Token.LrTable = LrTable
  196.  
  197.     (* structure Actions contains the functions which mantain the
  198.        semantic values stack in the parser.  Void is used to provide
  199.        a default value for the semantic stack.
  200.      *)
  201.  
  202.     structure Actions : 
  203.       sig
  204.           val actions : int * pos *
  205.            (LrTable.state * (svalue * pos * pos)) list * arg->
  206.                  LrTable.nonterm * (svalue * pos * pos) *
  207.              ((LrTable.state *(svalue * pos * pos)) list)
  208.           val void : svalue
  209.           val extract : svalue -> result
  210.       end
  211.  
  212.     (* structure EC contains information used to improve error
  213.        recovery in an error-correcting parser *)
  214.  
  215.     structure EC :
  216.        sig
  217.      val is_keyword : LrTable.term -> bool
  218.          val noShift : LrTable.term -> bool
  219.          val preferred_subst : LrTable.term -> LrTable.term list
  220.          val preferred_insert : LrTable.term -> bool
  221.          val errtermvalue : LrTable.term -> svalue
  222.          val showTerminal : LrTable.term -> string
  223.          val terms: LrTable.term list
  224.        end
  225.  
  226.     (* table is the LR table for the parser *)
  227.  
  228.     val table : LrTable.table
  229.     end
  230.  
  231. (* signature PARSER is the signature that most user parsers created by 
  232.    SML-Yacc will match.
  233. *)
  234.  
  235. signature PARSER =
  236.     sig
  237.         structure Token : TOKEN
  238.     structure Stream : STREAM
  239.     exception ParseError
  240.  
  241.     (* type pos is the type of line numbers *)
  242.  
  243.     type pos
  244.  
  245.     (* type result is the type of the result from the parser *)
  246.  
  247.     type result
  248.  
  249.          (* the type of the user-supplied argument to the parser *)
  250.      type arg
  251.     
  252.     (* type svalue is the type of semantic values for the semantic value
  253.        stack
  254.      *)
  255.  
  256.     type svalue
  257.  
  258.     (* val makeLexer is used to create a stream of tokens for the parser *)
  259.  
  260.     val makeLexer : (int -> string) ->
  261.              (svalue,pos) Token.token Stream.stream
  262.  
  263.     (* val parse takes a stream of tokens and a function to print
  264.        errors and returns a value of type result and a stream containing
  265.        the unused tokens
  266.      *)
  267.  
  268.     val parse : int * ((svalue,pos) Token.token Stream.stream) *
  269.             (string * pos * pos -> unit) * arg ->
  270.                 result * (svalue,pos) Token.token Stream.stream
  271.  
  272.     val sameToken : (svalue,pos) Token.token * (svalue,pos) Token.token ->
  273.                 bool
  274.      end
  275.  
  276. (* signature ARG_PARSER is the signature that will be matched by parsers whose
  277.     lexer takes an additional argument.
  278. *)
  279.  
  280. signature ARG_PARSER = 
  281.     sig
  282.         structure Token : TOKEN
  283.     structure Stream : STREAM
  284.     exception ParseError
  285.  
  286.     type arg
  287.     type lexarg
  288.     type pos
  289.     type result
  290.     type svalue
  291.  
  292.     val makeLexer : (int -> string) -> lexarg ->
  293.              (svalue,pos) Token.token Stream.stream
  294.     val parse : int * ((svalue,pos) Token.token Stream.stream) *
  295.             (string * pos * pos -> unit) * arg ->
  296.                 result * (svalue,pos) Token.token Stream.stream
  297.  
  298.     val sameToken : (svalue,pos) Token.token * (svalue,pos) Token.token ->
  299.                 bool
  300.      end
  301.  
  302. (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)
  303.  
  304. (* Stream: a structure implementing a lazy stream.  The signature STREAM
  305.    is found in base.sig *)
  306.  
  307. abstraction Stream : STREAM =
  308. struct
  309.    datatype 'a str = EVAL of 'a * 'a str ref | UNEVAL of (unit->'a)
  310.  
  311.    type 'a stream = 'a str ref
  312.  
  313.    fun get(ref(EVAL t)) = t
  314.      | get(s as ref(UNEVAL f)) = 
  315.         let val t = (f(), ref(UNEVAL f)) in s := EVAL t; t end
  316.  
  317.    fun streamify f = ref(UNEVAL f)
  318.    fun cons(a,s) = ref(EVAL(a,s))
  319.  
  320. end;
  321. (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)
  322.  
  323. structure LrTable : LR_TABLE = 
  324.     struct
  325.     open Array List
  326.     infix 9 sub
  327.     datatype ('a,'b) pairlist = EMPTY
  328.                   | PAIR of 'a * 'b * ('a,'b) pairlist
  329.     datatype term = T of int
  330.     datatype nonterm = NT of int
  331.     datatype state = STATE of int
  332.     datatype action = SHIFT of state
  333.             | REDUCE of int (* rulenum from grammar *)
  334.             | ACCEPT
  335.             | ERROR
  336.     exception Goto of state * nonterm
  337.     type table = {states: int, rules : int,initialState: state,
  338.               action: ((term,action) pairlist * action) array,
  339.               goto :  (nonterm,state) pairlist array}
  340.     val numStates = fn ({states,...} : table) => states
  341.     val numRules = fn ({rules,...} : table) => rules
  342.     val describeActions =
  343.        fn ({action,...} : table) => 
  344.                fn (STATE s) => action sub s
  345.     val describeGoto =
  346.        fn ({goto,...} : table) =>
  347.                fn (STATE s) => goto sub s
  348.     fun findTerm (T term,row,default) =
  349.         let fun find (PAIR (T key,data,r)) =
  350.                if key < term then find r
  351.                else if key=term then data
  352.                else default
  353.            | find EMPTY = default
  354.         in find row
  355.         end
  356.     fun findNonterm (NT nt,row) =
  357.         let fun find (PAIR (NT key,data,r)) =
  358.                if key < nt then find r
  359.                else if key=nt then SOME data
  360.                else NONE
  361.            | find EMPTY = NONE
  362.         in find row
  363.         end
  364.     val action = fn ({action,...} : table) =>
  365.         fn (STATE state,term) =>
  366.           let val (row,default) = action sub state
  367.           in findTerm(term,row,default)
  368.           end
  369.     val goto = fn ({goto,...} : table) =>
  370.             fn (a as (STATE state,nonterm)) =>
  371.               case findNonterm(nonterm,goto sub state)
  372.               of SOME state => state
  373.                | NONE => raise (Goto a)
  374.     val initialState = fn ({initialState,...} : table) => initialState
  375.     val mkLrTable = fn {actions,gotos,initialState,numStates,numRules} =>
  376.          ({action=actions,goto=gotos,
  377.            states=numStates,
  378.            rules=numRules,
  379.                initialState=initialState} : table)
  380. end;
  381. (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)
  382.  
  383. (* functor Join creates a user parser by putting together a Lexer structure,
  384.    an LrValues structure, and a polymorphic parser structure.  Note that
  385.    the Lexer and LrValues structure must share the type pos (i.e. the type
  386.    of line numbers), the type svalues for semantic values, and the type
  387.    of tokens.
  388. *)
  389.  
  390. functor Join(structure Lex : LEXER
  391.          structure ParserData: PARSER_DATA
  392.          structure LrParser : LR_PARSER
  393.          sharing ParserData.LrTable = LrParser.LrTable
  394.          sharing ParserData.Token = LrParser.Token
  395.          sharing type Lex.UserDeclarations.svalue = ParserData.svalue
  396.          sharing type Lex.UserDeclarations.pos = ParserData.pos
  397.          sharing type Lex.UserDeclarations.token = ParserData.Token.token)
  398.          : PARSER =
  399. struct
  400.     structure Token = ParserData.Token
  401.     structure Stream = LrParser.Stream
  402.  
  403.     exception ParseError = LrParser.ParseError
  404.  
  405.     type arg = ParserData.arg
  406.     type pos = ParserData.pos
  407.     type result = ParserData.result
  408.     type svalue = ParserData.svalue
  409.     val makeLexer = LrParser.Stream.streamify o Lex.makeLexer
  410.     val parse = fn (lookahead,lexer,error,arg) =>
  411.     (fn (a,b) => (ParserData.Actions.extract a,b))
  412.      (LrParser.parse {table = ParserData.table,
  413.             lexer=lexer,
  414.         lookahead=lookahead,
  415.         saction = ParserData.Actions.actions,
  416.         arg=arg,
  417.         void= ParserData.Actions.void,
  418.             ec = {is_keyword = ParserData.EC.is_keyword,
  419.               noShift = ParserData.EC.noShift,
  420.               preferred_subst = ParserData.EC.preferred_subst,
  421.               preferred_insert= ParserData.EC.preferred_insert,
  422.               errtermvalue = ParserData.EC.errtermvalue,
  423.               error=error,
  424.               showTerminal = ParserData.EC.showTerminal,
  425.               terms = ParserData.EC.terms}}
  426.       )
  427.      val sameToken = Token.sameToken
  428. end
  429.  
  430. (* functor JoinWithArg creates a variant of the parser structure produced 
  431.    above.  In this case, the makeLexer take an additional argument before
  432.    yielding a value of type unit -> (svalue,pos) token
  433.  *)
  434.  
  435. functor JoinWithArg(structure Lex : ARG_LEXER
  436.          structure ParserData: PARSER_DATA
  437.          structure LrParser : LR_PARSER
  438.          sharing ParserData.LrTable = LrParser.LrTable
  439.          sharing ParserData.Token = LrParser.Token
  440.          sharing type Lex.UserDeclarations.svalue = ParserData.svalue
  441.          sharing type Lex.UserDeclarations.pos = ParserData.pos
  442.          sharing type Lex.UserDeclarations.token = ParserData.Token.token)
  443.          : ARG_PARSER  =
  444. struct
  445.     structure Token = ParserData.Token
  446.     structure Stream = LrParser.Stream
  447.  
  448.     exception ParseError = LrParser.ParseError
  449.  
  450.     type arg = ParserData.arg
  451.     type lexarg = Lex.UserDeclarations.arg
  452.     type pos = ParserData.pos
  453.     type result = ParserData.result
  454.     type svalue = ParserData.svalue
  455.  
  456.     val makeLexer = fn s => fn arg =>
  457.          LrParser.Stream.streamify (Lex.makeLexer s arg)
  458.     val parse = fn (lookahead,lexer,error,arg) =>
  459.     (fn (a,b) => (ParserData.Actions.extract a,b))
  460.      (LrParser.parse {table = ParserData.table,
  461.             lexer=lexer,
  462.         lookahead=lookahead,
  463.         saction = ParserData.Actions.actions,
  464.         arg=arg,
  465.         void= ParserData.Actions.void,
  466.             ec = {is_keyword = ParserData.EC.is_keyword,
  467.               noShift = ParserData.EC.noShift,
  468.               preferred_subst = ParserData.EC.preferred_subst,
  469.               preferred_insert= ParserData.EC.preferred_insert,
  470.               errtermvalue = ParserData.EC.errtermvalue,
  471.               error=error,
  472.               showTerminal = ParserData.EC.showTerminal,
  473.               terms = ParserData.EC.terms}}
  474.       )
  475.     val sameToken = Token.sameToken
  476. end;
  477. (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)
  478.  
  479. (* parser.sml:  This is a parser driver for LR tables with an error-recovery
  480.    routine added to it.  The routine used is described in detail in this
  481.    article:
  482.  
  483.     'A Practical Method for LR and LL Syntactic Error Diagnosis and
  484.      Recovery', by M. Burke and G. Fisher, ACM Transactions on
  485.      Programming Langauges and Systems, Vol. 9, No. 2, April 1987,
  486.      pp. 164-197.
  487.  
  488.     This program is an implementation is the partial, deferred method discussed
  489.     in the article.  The algorithm and data structures used in the program
  490.     are described below.  
  491.  
  492.     This program assumes that all semantic actions are delayed.  A semantic
  493.     action should produce a function from unit -> value instead of producing the
  494.     normal value.  The parser returns the semantic value on the top of the
  495.     stack when accept is encountered.  The user can deconstruct this value
  496.     and apply the unit -> value function in it to get the answer.
  497.  
  498.     It also assumes that the lexer is a lazy stream.
  499.  
  500.     Data Structures:
  501.     ----------------
  502.     
  503.     * The parser:
  504.  
  505.        The state stack has the type
  506.  
  507.          (state * (semantic value * line # * line #)) list
  508.  
  509.        The parser keeps a queue of (state stack * lexer pair).  A lexer pair
  510.      consists of a terminal * value pair and a lexer.  This allows the 
  511.      parser to reconstruct the states for terminals to the left of a
  512.      syntax error, and attempt to make error corrections there.
  513.  
  514.        The queue consists of a pair of lists (x,y).  New additions to
  515.      the queue are cons'ed onto y.  The first element of x is the top
  516.      of the queue.  If x is nil, then y is reversed and used
  517.      in place of x.
  518.  
  519.     Algorithm:
  520.     ----------
  521.  
  522.     * The steady-state parser:  
  523.  
  524.         This parser keeps the length of the queue of state stacks at
  525.     a steady state by always removing an element from the front when
  526.     another element is placed on the end.
  527.  
  528.         It has these arguments:
  529.  
  530.        stack: current stack
  531.        queue: value of the queue
  532.        lexPair ((terminal,value),lex stream)
  533.  
  534.     When SHIFT is encountered, the state to shift to and the value are
  535.     are pushed onto the state stack.  The state stack and lexPair are
  536.     placed on the queue.  The front element of the queue is removed.
  537.  
  538.     When REDUCTION is encountered, the rule is applied to the current
  539.     stack to yield a triple (nonterm,value,new stack).  A new
  540.     stack is formed by adding (goto(top state of stack,nonterm),value)
  541.     to the stack.
  542.  
  543.     When ACCEPT is encountered, the top value from the stack and the
  544.     lexer are returned.
  545.  
  546.     When an ERROR is encountered, fixError is called.  FixError
  547.     takes the arguments to the parser, fixes the error if possible and
  548.         returns a new set of arguments.
  549.  
  550.     * The distance-parser:
  551.  
  552.     This parser includes an additional argument distance.  It pushes
  553.     elements on the queue until it has parsed distance tokens, or an
  554.     ACCEPT or ERROR occurs.  It returns a stack, lexer, the number of
  555.     tokens left unparsed, a queue, and an action option.
  556. *)
  557.  
  558. signature FIFO = 
  559.   sig type 'a queue
  560.       val empty : 'a queue
  561.       exception Empty
  562.       val get : 'a queue -> 'a * 'a queue
  563.       val put : 'a * 'a queue -> 'a queue
  564.   end
  565.  
  566. (* drt (12/15/89) -- the functor should be used in development work, but
  567.    it wastes space in the release version.
  568.  
  569. functor ParserGen(structure LrTable : LR_TABLE
  570.           structure Stream : STREAM) : LR_PARSER =
  571. *)
  572.  
  573. abstraction LrParser : LR_PARSER =
  574.    struct
  575.       structure LrTable = LrTable
  576.       structure Stream = Stream
  577.  
  578.       structure Token : TOKEN =
  579.     struct
  580.         structure LrTable = LrTable
  581.         datatype ('a,'b) token = TOKEN of LrTable.term * ('a * 'b * 'b)
  582.         val sameToken = fn (TOKEN(t,_),TOKEN(t',_)) => t=t'
  583.         end
  584.  
  585.       open LrTable
  586.       open Token
  587.  
  588.       val DEBUG1 = false
  589.       val DEBUG2 = false
  590.       exception ParseError
  591.       exception ParseImpossible of int
  592.  
  593.       abstraction Fifo : FIFO =
  594.         struct
  595.       type 'a queue = ('a list * 'a list)
  596.       val empty = (nil,nil)
  597.       exception Empty
  598.       fun get(a::x, y) = (a, (x,y))
  599.         | get(nil, nil) = raise Empty
  600.         | get(nil, y) = get(rev y, nil)
  601.        fun put(a,(x,y)) = (x,a::y)
  602.         end
  603.  
  604.       type ('a,'b) elem = (state * ('a * 'b * 'b))
  605.       type ('a,'b) stack = ('a,'b) elem list
  606.       type ('a,'b) lexv = ('a,'b) token
  607.       type ('a,'b) lexpair = ('a,'b) lexv * (('a,'b) lexv Stream.stream)
  608.       type ('a,'b) distanceParse =
  609.          ('a,'b) lexpair *
  610.          ('a,'b) stack * 
  611.          (('a,'b) stack * ('a,'b) lexpair) Fifo.queue *
  612.          int ->
  613.            ('a,'b) lexpair *
  614.            ('a,'b) stack * 
  615.            (('a,'b) stack * ('a,'b) lexpair) Fifo.queue *
  616.            int *
  617.            action option
  618.  
  619.       type ('a,'b) ecRecord =
  620.      {is_keyword : term -> bool,
  621.           preferred_subst : term -> term list,
  622.       preferred_insert : term -> bool,
  623.       error : string * 'b * 'b -> unit,
  624.       errtermvalue : term -> 'a,
  625.       terms : term list,
  626.       showTerminal : term -> string,
  627.       noShift : term -> bool}
  628.  
  629.       local 
  630.      val print = fn s => output(std_out,s)
  631.      val println = fn s => (print s; print "\n")
  632.      val showState = fn (STATE s) => "STATE " ^ (makestring s)
  633.       in
  634.         fun printStack(stack: ('a,'b) stack, n: int) =
  635.          case stack
  636.            of (state,_) :: rest =>
  637.                  (print("\t" ^ makestring n ^ ": ");
  638.                   println(showState state);
  639.                   printStack(rest, n+1))
  640.             | nil => ()
  641.                 
  642.         fun prAction showTerminal
  643.          (stack as (state,_) :: _, next as (TOKEN (term,_),_), action) =
  644.              (println "Parse: state stack:";
  645.               printStack(stack, 0);
  646.               print("       state="
  647.                          ^ showState state    
  648.                          ^ " next="
  649.                          ^ showTerminal term
  650.                          ^ " action="
  651.                         );
  652.               case action
  653.                 of SHIFT state => println ("SHIFT " ^ (showState state))
  654.                  | REDUCE i => println ("REDUCE " ^ (makestring i))
  655.                  | ERROR => println "ERROR"
  656.          | ACCEPT => println "ACCEPT")
  657.         | prAction _ (_,_,action) = ()
  658.      end
  659.  
  660.     (* ssParse: parser which maintains the queue of (state * lexvalues) in a
  661.     steady-state.  It takes a table, showTerminal function, saction
  662.     function, and fixError function.  It parses until an ACCEPT is
  663.     encountered, or an exception is raised.  When an error is encountered,
  664.     fixError is called with the arguments of parseStep (lexv,stack,and
  665.     queue).  It returns the lexv, and a new stack and queue adjusted so
  666.     that the lexv can be parsed *)
  667.     
  668.     val ssParse =
  669.       fn (table,showTerminal,saction,fixError,arg) =>
  670.     let val prAction = prAction showTerminal
  671.         val action = LrTable.action table
  672.         val goto = LrTable.goto table
  673.         fun parseStep(args as
  674.              (lexPair as (TOKEN (terminal, value as (_,leftPos,_)),
  675.                       lexer
  676.                       ),
  677.               stack as (state,_) :: _,
  678.               queue)) =
  679.           let val nextAction = action (state,terminal)
  680.               val _ = if DEBUG1 then prAction(stack,lexPair,nextAction)
  681.               else ()
  682.           in case nextAction
  683.          of SHIFT s =>
  684.           let val newStack = (s,value) :: stack
  685.               val newLexPair = Stream.get lexer
  686.               val (_,newQueue) =Fifo.get(Fifo.put((newStack,newLexPair),
  687.                                 queue))
  688.           in parseStep(newLexPair,(s,value)::stack,newQueue)
  689.           end
  690.          | REDUCE i =>
  691.              (case saction(i,leftPos,stack,arg)
  692.               of (nonterm,value,stack as (state,_) :: _) =>
  693.                   parseStep(lexPair,(goto(state,nonterm),value)::stack,
  694.                     queue)
  695.                | _ => raise (ParseImpossible 197))
  696.          | ERROR => parseStep(fixError args)
  697.          | ACCEPT => 
  698.             (case stack
  699.              of (_,(topvalue,_,_)) :: _ =>
  700.                 let val (token,restLexer) = lexPair
  701.                 in (topvalue,Stream.cons(token,restLexer))
  702.                 end
  703.               | _ => raise (ParseImpossible 202))
  704.           end
  705.         | parseStep _ = raise (ParseImpossible 204)
  706.     in parseStep
  707.     end
  708.  
  709.     (*  distanceParse: parse until n tokens are shifted, or accept or
  710.     error are encountered.  Takes a table, showTerminal function, and
  711.     semantic action function.  Returns a parser which takes a lexPair
  712.     (lex result * lexer), a state stack, a queue, and a distance
  713.     (must be > 0) to parse.  The parser returns a new lex-value, a stack
  714.     with the nth token shifted on top, a queue, a distance, and action
  715.     option. *)
  716.  
  717.     val distanceParse =
  718.       fn (table,showTerminal,saction,arg) =>
  719.     let val prAction = prAction showTerminal
  720.         val action = LrTable.action table
  721.         val goto = LrTable.goto table
  722.         fun parseStep(lexPair,stack,queue,0) = (lexPair,stack,queue,0,NONE)
  723.           | parseStep(lexPair as (TOKEN (terminal, value as (_,leftPos,_)),
  724.                       lexer
  725.                      ),
  726.               stack as (state,_) :: _,
  727.               queue,distance) =
  728.           let val nextAction = action(state,terminal)
  729.               val _ = if DEBUG1 then prAction(stack,lexPair,nextAction)
  730.               else ()
  731.           in case nextAction
  732.          of SHIFT s =>
  733.           let val newStack = (s,value) :: stack
  734.               val newLexPair = Stream.get lexer
  735.           in parseStep(newLexPair,(s,value)::stack,
  736.                    Fifo.put((newStack,newLexPair),queue),distance-1)
  737.           end
  738.          | REDUCE i =>
  739.             (case saction(i,leftPos,stack,arg)
  740.               of (nonterm,value,stack as (state,_) :: _) =>
  741.                  parseStep(lexPair,(goto(state,nonterm),value)::stack,
  742.                  queue,distance)
  743.               | _ => raise (ParseImpossible 240))
  744.          | ERROR => (lexPair,stack,queue,distance,SOME nextAction)
  745.          | ACCEPT => (lexPair,stack,queue,distance,SOME nextAction)
  746.           end
  747.        | parseStep _ = raise (ParseImpossible 242)
  748.     in parseStep : ('_a,'_b) distanceParse 
  749.     end
  750.  
  751. (* mkFixError: function to create fixError function which adjusts parser state
  752.    so that parse may continue in the presence of an error *)
  753.  
  754. val mkFixError = fn ({is_keyword,preferred_subst,terms,errtermvalue,
  755.               preferred_insert,noShift,
  756.               showTerminal,error,...} : ('_a,'_b) ecRecord,
  757.               distanceParse : ('_a,'_b) distanceParse,
  758.               minAdvance,maxAdvance) =>
  759.   let fun FixError(lexv as (TOKEN (term,value as (_,leftPos,_)),_),
  760.            stack,queue) =
  761.     let val lexVList = map (fn t => TOKEN (t,(errtermvalue t,leftPos,leftPos)))
  762.                terms
  763.     val _ = if DEBUG2 then
  764.             error("syntax error found at " ^ (showTerminal term),
  765.                   leftPos,leftPos)
  766.         else ()
  767.  
  768.     val minDelta = 3
  769.  
  770.     (* pull all the state * lexv elements from the queue *)
  771.  
  772.     val stateList = 
  773.        let fun f q = let val (elem,newQueue) = Fifo.get q
  774.              in elem :: (f newQueue)
  775.              end handle Fifo.Empty => nil
  776.        in f queue
  777.        end
  778.  
  779.     (* now number elements of stateList, giving distance from
  780.        error token *)
  781.  
  782.     val (_,numStateList) = List.fold (fn (a,(num,r)) => (num+1,(a,num)::r))
  783.                 stateList (0,nil)
  784.  
  785.     (* Represent the set of potential changes as a linked list.
  786.  
  787.        Values of datatype Change hold information about a potential change.
  788.  
  789.        oper = oper to be applied
  790.        pos = the # of the element in stateList that would be altered.
  791.        distance = the number of tokens beyond the error token which the
  792.          change allows us to parse.
  793.        new = new terminal * value pair at that point
  794.        orig = original terminal * value pair at the point being changed.
  795.      *)
  796.  
  797.     datatype oper = INSERT | DELETE  | SUBST
  798.     datatype ('a,'b) change = CHANGE of
  799.        {oper : oper, pos : int, distance : int,
  800.         new : ('a,'b) lexv, orig : ('a,'b) lexv}
  801.  
  802.     val operToString = 
  803.            fn INSERT => "INSERT "
  804.         | SUBST  => "SUBST "
  805.         | DELETE => "DELETE "
  806.  
  807.      val printChange = fn c =>
  808.       let val CHANGE {oper,distance,new=TOKEN (t,_),
  809.               orig=TOKEN (t',_),pos,...} = c
  810.       in (print ("{distance= " ^ (makestring distance));
  811.           print (",orig = " ^ (showTerminal t'));
  812.           print (",new = " ^ (showTerminal t));
  813.           print (",oper= " ^ (operToString oper));
  814.           print (",pos= " ^ (makestring pos));
  815.           print "}\n")
  816.       end
  817.  
  818.     val printChangeList = app printChange
  819.  
  820. (* parse: given a lexPair, a stack, and the distance from the error
  821.    token, return the distance past the error token that we are able to parse.*)
  822.  
  823.     fun parse (lexPair,stack,queuePos : int) =
  824.         let val (_,_,_,distance,action) =
  825.           distanceParse(lexPair,stack,Fifo.empty,queuePos+maxAdvance+1)
  826.         in maxAdvance - distance - 1
  827.         end
  828.  
  829. (* foldStateList: accumulates results while scanning numStateList *)
  830.  
  831.  
  832.     fun foldStateList f start = List.fold f numStateList start
  833.  
  834. (* foldLexVList: accumulates results while scanning lexVList *)
  835.  
  836.     fun foldLexVList f start = List.fold f lexVList start
  837.  
  838. (* deleteFold: function which accumulates results of deleting the
  839.    current terminal.  Does not delete the current terminal if that terminal
  840.    cannot be shifted *)
  841.  
  842.     val deleteFold =
  843.         fn (((stack,lexPair as (orig as TOKEN (term,_),lexer)),
  844.             queuePos),r) =>
  845.          if noShift term then r
  846.          else
  847.            let val newLexPair as (new,_) = Stream.get lexer
  848.                val distance = parse(newLexPair,stack,queuePos-1)
  849.            in if distance >= minAdvance then
  850.             CHANGE {pos=queuePos,distance=distance,orig=orig,
  851.                 new=new,oper=DELETE} :: r
  852.               else r
  853.            end
  854.  
  855.  
  856. (* insertFold: accumulate results of trying to insert tokens before
  857.    the current terminal *)
  858.  
  859.     val insertFold =
  860.        fn (((stack,lexPair as (orig,lexer)),queuePos),r) =>
  861.         let val lexer = Stream.cons lexPair
  862.         in foldLexVList (fn (newLexV,r) =>
  863.         let val distance = parse((newLexV,lexer),stack,queuePos+1)
  864.         in if distance >= minAdvance
  865.              then CHANGE{pos=queuePos,distance=distance,orig=orig,
  866.                     new=newLexV,oper=INSERT} :: r
  867.              else r
  868.         end) r
  869.         end
  870.  
  871. (* substFold: accumulate results of deleting the current terminal
  872.    and then trying to insert tokens *)
  873.  
  874.     val substFold =
  875.         fn (((stack,lexPair as (orig as TOKEN (term,_),lexer)),queuePos),
  876.         r) =>
  877.           if noShift term then r
  878.           else
  879.           foldLexVList (fn (newLexV,r) =>
  880.            let val distance = parse((newLexV,lexer),stack,queuePos)
  881.            in if distance >= minAdvance then
  882.                CHANGE{pos=queuePos,distance=distance,orig=orig,
  883.                   new=newLexV,oper=SUBST} :: r
  884.              else r
  885.            end) r
  886.  
  887.     val changes = (foldStateList insertFold nil) @
  888.               (foldStateList substFold nil) @
  889.                 (foldStateList deleteFold nil)
  890.  
  891.     val findMaxDist = fn l => 
  892.       fold (fn (CHANGE {distance,...},high) => max(distance,high)) l 0
  893.  
  894. (* maxDist: max distance past error taken that we could parse *)
  895.  
  896.     val maxDist = findMaxDist changes
  897.  
  898. (* sieve: keep only the elements of a list for which pred is true *)
  899.  
  900.     val sieve = fn pred => fn l => 
  901.       fold (fn (elem,rest) => if pred elem then elem::rest else rest) l nil
  902.  
  903. (* remove changes which did not parse maxDist tokens past the error token *)
  904.  
  905.     val changes = sieve (fn CHANGE{distance=a,...} => a = maxDist) changes
  906.  
  907. (* Find preferred elements *)
  908.  
  909.         val preferredInsertChanges =
  910.         sieve (fn CHANGE {new=TOKEN (term,_),oper=INSERT,...} => 
  911.                  preferred_insert term
  912.                 | _ => false) changes
  913.  
  914.         val preferredSubstChanges =
  915.         sieve
  916.             (fn CHANGE {new=TOKEN(t,_),orig=TOKEN (t',_),
  917.                 oper=SUBST,...} =>
  918.               List.exists (fn a => a =t) (preferred_subst t')
  919.               | _ => false) changes
  920.  
  921.         val _ = if DEBUG2 then
  922.         (print "preferred insert:\n";
  923.          printChangeList preferredInsertChanges;
  924.          print "preferred subst:\n";
  925.          printChangeList preferredSubstChanges
  926.         ) else ()
  927.  
  928. (* Remove keywords which don't meet the long parse check
  929.    (minAdvance+minDelta) *)
  930.  
  931.          val changes =
  932.         sieve (fn CHANGE {new=TOKEN (term,_),distance,...} =>
  933.         (not (is_keyword term) orelse distance >= minAdvance+minDelta))
  934.             changes
  935.  
  936.  
  937.          val changes =
  938.            preferredInsertChanges @ (preferredSubstChanges @ changes)
  939.  
  940.          in case changes 
  941.          of (l as _ :: _) =>
  942.             let fun print_msg (CHANGE {new=TOKEN (term,_),oper,
  943.                        orig=TOKEN (t',(_,leftPos,rightPos)),
  944.                        ...}) =
  945.              let val s = 
  946.                case oper
  947.              of DELETE => "deleting " ^ (showTerminal t')
  948.               | INSERT => "inserting " ^ (showTerminal term)
  949.                   | SUBST => "replacing " ^ (showTerminal t') ^
  950.                    " with " ^ (showTerminal term)
  951.              in error ("syntax error: " ^ s,leftPos,rightPos)
  952.              end
  953.            
  954.            val a = 
  955.              (if length l > 1 andalso DEBUG2 then
  956.             (print "multiple fixes possible; could fix it by:\n";
  957.               map print_msg l;
  958.               print "chosen correction:\n")
  959.               else ();
  960.               print_msg (hd l); (hd l))
  961.  
  962.             (* findNth: find nth queue entry from the error
  963.                entry.  Returns the Nth queue entry and the  portion of
  964.                the queue from the beginning to the nth-1 entry.  The
  965.                error entry is at the end of the queue.
  966.  
  967.             Examples:
  968.  
  969.             queue = a b c d e
  970.                 findNth 0 = (e,a b c d)
  971.             findNth 1 =  (d,a b c)
  972.             *)
  973.  
  974.             val findNth = fn n =>
  975.              let fun f (h::t,0) = (h,rev t)
  976.                | f (h::t,n) = f(t,n-1)
  977.                | f (nil,_) = let exception FindNth
  978.                        in raise FindNth
  979.                        end
  980.              in f (rev stateList,n)
  981.              end
  982.         
  983.             val CHANGE {pos,oper,new=TOKEN (term,(value,_,_)),...} = a
  984.             val (last,queueFront) = findNth pos
  985.             val (stack,lexPair as (orig,lexer)) = last
  986.             val TOKEN (_,(_,leftPos,rightPos)) = orig
  987.              val newLexV = TOKEN (term,(value,leftPos,rightPos))
  988.  
  989.             val newLexPair =
  990.             case oper
  991.             of DELETE => Stream.get lexer
  992.              | SUBST => (newLexV,lexer)
  993.              | INSERT => (newLexV,Stream.cons lexPair)
  994.  
  995.             val restQueue = 
  996.              Fifo.put((stack,newLexPair),
  997.                   revfold Fifo.put queueFront Fifo.empty)
  998.  
  999.             val (lexPair,stack,queue,_,_) =
  1000.             distanceParse(newLexPair,stack,restQueue,pos)
  1001.  
  1002.           in (lexPair,stack,queue)
  1003.           end
  1004.       | nil => (error("syntax error found at " ^ (showTerminal term),
  1005.                   leftPos,leftPos); raise ParseError)
  1006.     end
  1007.      in FixError
  1008.      end
  1009.  
  1010.    val parse = fn {arg,table,lexer,saction,void,lookahead,
  1011.            ec=ec as {showTerminal,...} : ('_a,'_b) ecRecord} =>
  1012.     let val distance = 15   (* defer distance tokens *)
  1013.         val minAdvance = 1  (* must parse at least 1 token past error *)
  1014.         val maxAdvance = max(lookahead,0)(* max distance for parse check *)
  1015.         val lexPair = Stream.get lexer
  1016.         val (TOKEN (_,(_,leftPos,_)),_) = lexPair
  1017.         val startStack = [(initialState table,(void,leftPos,leftPos))]
  1018.         val startQueue = Fifo.put((startStack,lexPair),Fifo.empty)
  1019.         val distanceParse = distanceParse(table,showTerminal,saction,arg)
  1020.         val fixError = mkFixError(ec,distanceParse,minAdvance,maxAdvance)
  1021.         val ssParse = ssParse(table,showTerminal,saction,fixError,arg)
  1022.         fun loop (lexPair,stack,queue,_,SOME ACCEPT) =
  1023.            ssParse(lexPair,stack,queue)
  1024.           | loop (lexPair,stack,queue,0,_) = ssParse(lexPair,stack,queue)
  1025.           | loop (lexPair,stack,queue,distance,SOME ERROR) =
  1026.          let val (lexPair,stack,queue) = fixError(lexPair,stack,queue)
  1027.          in loop (distanceParse(lexPair,stack,queue,distance))
  1028.          end
  1029.           | loop _ = let exception ParseInternal
  1030.              in raise ParseInternal
  1031.              end
  1032.     in loop (distanceParse(lexPair,startStack,startQueue,distance))
  1033.     end
  1034.  end;
  1035.  
  1036. (* drt (12/15/89) -- needed only when the code above is functorized
  1037.  
  1038. structure LrParser = ParserGen(structure LrTable=LrTable
  1039.                  structure Stream=Stream);
  1040. *)
  1041.